home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Science / µSim 1.0 folder / Libs / MovableModal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  13.5 KB  |  506 lines  |  [TEXT/MMCC]

  1. #include    "UtilsSys7.h"
  2. #include    "CursorBalloon.h"
  3. #include    "Independents.h"
  4. #include    "MovableModal.h"
  5.  
  6. static void RecalcTextItems(FabWindowPtr w, RgnBalloonCursPtr theObj);
  7. static void DoMovableModalUpdate(DialogPtr dPtr);
  8. static void DimOrBlackenItems(EventRecord *e, WindowPtr w, Boolean active);
  9. static void DoMovableModalMenuEdit(short theItem);
  10. static void DoMovableModalDrag(WindowPtr w, Point p);
  11. static void getDragRectMovMod(WindowPtr w, RectPtr r);
  12.  
  13. static Handle    sControlItemList = nil;
  14. static short    sDefaultItem = 0, sCancelItem = 0;
  15.  
  16. #define    FabSetDialogDefaultItem(d, i)    sDefaultItem = i
  17. #define    FabSetDialogCancelItem(d, i)    sCancelItem = i
  18.  
  19. short HandleMovableModalDialog(/*ModalFilterProcPtr filterProc,*/
  20.                     dialogItemsPtr things,
  21.                     Point *dialogTopLeft,
  22.                     Boolean (*canAcceptDrag)(const HFSFlavor *),
  23.                     OSErr (*dialogDragReaction)(WindowPtr, const HFSFlavor *),
  24.                     void (*initProc)(DialogPtr),
  25.                     void (*cleanupProc)(DialogPtr),
  26.                     void (*userProc)(DialogPtr, Handle, short),
  27.                     void (*AdjustMenus)(void),
  28.                     void (*Handle_My_Menu)(long),
  29.                     void (*DomyKeyEvent)(EventRecord *),
  30.                     Boolean (*PreProcessKeyDown)(EventRecord *, DialogPtr),
  31.                     void (*PostProcessKeyDown)(EventRecord *, DialogPtr),
  32.                     void (*DoUpdate)(EventRecord *),
  33.                     void (*DoActivate)(EventRecord *),
  34.                     void (*DoHiLevEvent)(EventRecord *),
  35.                     void (*DoOSEvent)(EventRecord *),
  36.                     void (*DoIdle)(void),
  37.                     unsigned long minimumSleep,
  38.                     short resId)
  39. {
  40. EventRecord    lMyEvent;
  41. Rect    box;
  42. Handle    item;
  43. GrafPtr    port;
  44. long    myRefCon;
  45. DialogPtr    dPtr;
  46. DialogPtr    dSelPtr;
  47. WindowPtr    w;
  48. Ptr    myStorage;
  49. unsigned long    movablemodalSleep;
  50. dialogItemsPtr    spanPtr;
  51. dialogItemsPtr    itemToBeActivated;
  52. RgnHandle    theRgn;
  53. long    menuSelected;
  54. short    wMenu;
  55. short    code, type, theItemHit = memFullErr;
  56. short    theGroup, theFakeItem, lastItemClosingDialog = cancel;
  57. short    theType, iNum;
  58. short    editTextExists = 0;
  59. unsigned char    keypressed;
  60. Boolean    dialoging;
  61.  
  62. InitCursor();
  63. myStorage = NewPtrClear(sizeof(FabWindowRecord));
  64. if (myStorage) {
  65.     dPtr = GetNewDialog(resId, myStorage, (DialogPtr)-1L);
  66.     if (dPtr) {
  67.         GetPort(&port);
  68.         SetPort(dPtr);
  69.     
  70.         InitFabWindow((FabWindowPtr)dPtr);
  71.         SetUpdate(dPtr, DoMovableModalUpdate);
  72.         SetActivate(dPtr, DimOrBlackenItems);
  73.         SetGetDragRect(dPtr, getDragRectMovMod);
  74.         SetCanIAcceptDrag(dPtr, canAcceptDrag);
  75.         SetDragReaction(dPtr, dialogDragReaction);
  76.         
  77.         if (dialogTopLeft) {
  78.             if (IsOnScreenWeak(*dialogTopLeft))
  79.                 MoveWindow(dPtr, dialogTopLeft->h, dialogTopLeft->v, false);
  80.             }
  81.  
  82.         sDefaultItem = 0;
  83.         sCancelItem = 0;
  84.         
  85.         spanPtr = things;
  86.         sControlItemList = NewHandle(0);
  87.         if (sControlItemList) {
  88.             while (iNum = spanPtr->itemNumber) {
  89.                 myRefCon = spanPtr->refCon;
  90.                 GetDialogItem(dPtr, iNum, &type, &item, &box);
  91.                 theType = type & itemDisable ? type - itemDisable : type;
  92.                 switch(theType) {
  93.                     case ctrlItem+btnCtrl:
  94.                             {
  95.                             if (myRefCon == 1L)
  96.                                 FabSetDialogDefaultItem(dPtr, iNum)
  97.                                 ;
  98.                             else if (myRefCon == 2L)
  99.                                 lastItemClosingDialog = iNum;
  100.                             if (iNum == cancel)
  101.                                 FabSetDialogCancelItem(dPtr, iNum)
  102.                                 ;
  103.                             }
  104.                         SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  105.                         PtrAndHand(&item, sControlItemList, sizeof item);
  106.                         break;
  107.                     case ctrlItem+chkCtrl:
  108.                     case ctrlItem+radCtrl:
  109.                         if (myRefCon > 0) {
  110.                             SetControlValue((ControlHandle)item, 1);
  111.                             if (userProc)
  112.                                 userProc(dPtr, item, iNum);
  113.                             }
  114.         /*                else if (myRefCon == 0) {
  115.                             if (userProc)
  116.                                 userProc(dPtr, item, iNum);
  117.                             }*/
  118.                         else if (myRefCon < 0)
  119.                             HiliteControl((ControlHandle)item, 255);
  120.                         SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  121.                         PtrAndHand(&item, sControlItemList, sizeof item);
  122.                         break;
  123.                     case ctrlItem+resCtrl:
  124.                         if (myRefCon)
  125.                             SetControlValue((ControlHandle)item, myRefCon);
  126.                         SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  127.                         PtrAndHand(&item, sControlItemList, sizeof item);
  128.                         break;
  129.                     case statText:
  130.                         if (myRefCon)
  131.                             SetDialogItemText(item, (StringPtr)myRefCon);
  132.                         break;
  133.                     case editText:
  134.                         SetDialogItemText(item, (StringPtr)myRefCon);
  135.                         if(editTextExists == 0) {
  136.                             editTextExists = iNum;
  137.                             }
  138.                         theRgn = NewRgn();
  139.                         RectRgn(theRgn, &box);
  140.                         InstallRgnHandler((FabWindowPtr)dPtr, theRgn, RecalcTextItems, GetCursor(iBeamCursor),
  141.                                     0, 0, iNum);
  142.                         break;
  143.             //        case iconItem:
  144.             //            break;
  145.             //        case picItem:
  146.             //            break;
  147.                     case userItem:
  148.                         SetDialogItem(dPtr, iNum, type, (Handle)myRefCon, &box);
  149.                         break;
  150.                     }
  151.                 spanPtr++;
  152.                 }
  153.             item = nil;
  154.             PtrAndHand(&item, sControlItemList, sizeof item);
  155.             if (editTextExists) {
  156.                 ResizeObjects((FabWindowPtr)dPtr);
  157.                 RecalcGlobalCoords((FabWindowPtr)dPtr);
  158.                 (void) EventAvail(0, &lMyEvent);
  159.                 RecalcMouseRegion(dPtr, lMyEvent.where);
  160.                 movablemodalSleep = GetCaretTime();
  161.                 }
  162.             else
  163.                 movablemodalSleep = -1L;
  164.             if (initProc)
  165.                 initProc(dPtr);
  166. //            (void)TEFeatureFlag(teFOutlineHilite, TEBitSet, ((DialogPeek)dPtr)->textH);
  167.             SelectDialogItemText(dPtr, editTextExists, 0, SHRT_MAX);
  168.             ShowWindow(dPtr);
  169.         
  170.             dialoging = true;
  171.             HiliteMenu(0);
  172.             AdjustMenus();
  173.             DrawMenuBar();
  174.  
  175.             movablemodalSleep = MIN(minimumSleep, movablemodalSleep);
  176.             do {
  177.                 if (WaitNextEvent(everyEvent - diskMask, &lMyEvent, movablemodalSleep, mouseRgn)) {
  178.                     if (IsDialogEvent(&lMyEvent)) {
  179.                         theFakeItem = 0;
  180.                         switch (lMyEvent.what) {
  181.                             //case mouseDown :
  182.                             //    DebugStr("\pMouse Down!");
  183.                             //    break;
  184.                             case keyDown:
  185.                             case autoKey:
  186.                                 keypressed = CHARFROMMESSAGE(lMyEvent.message);
  187.                                 if (PreProcessKeyDown ? PreProcessKeyDown(&lMyEvent, dPtr) : true) {
  188.                                     if (keypressed == 3) {
  189.                                         theFakeItem = sDefaultItem;
  190.                                         if (theFakeItem == 0)
  191.                                             theFakeItem = ok;
  192.                                         }
  193.                                     else if (keypressed == 13 && sDefaultItem) {
  194.                                         theFakeItem = sDefaultItem;
  195.                                         }
  196.                                     else if (CmdPeriodOrEsc(&lMyEvent)) {
  197.                                         theFakeItem = sCancelItem;
  198.                                         }
  199.                                     else if (keypressed == 27) {
  200.                                         //SelIText(dPtr, ((DialogPeek)dPtr)->editField + 1, 0, SHRT_MAX);
  201.                                         DialogDelete(dPtr);
  202.                                         }
  203.                                     else if ((unsigned short)lMyEvent.message == kHelpKey) {
  204.                                         (void)HMSetBalloons(1 - HMGetBalloons());
  205.                                         //RecalcMouseRegion(dPtr, lMyEvent.where);
  206.                                         }
  207.                                     else
  208.                                         (void) DialogSelect(&lMyEvent, &dSelPtr, &theItemHit);
  209.                                     if (theFakeItem)
  210.                                         FlashButton(dPtr, theFakeItem);
  211.                                     if (PostProcessKeyDown)
  212.                                         PostProcessKeyDown(&lMyEvent, dPtr);
  213.                                     }
  214.                                 break;
  215.                             case updateEvt:
  216.                                 if ((DialogPtr)lMyEvent.message == dPtr) {
  217.                                     BeginUpdate(dPtr);
  218.                                     DoMovableModalUpdate(dPtr);
  219.                                     EndUpdate(dPtr);
  220.                                     }
  221.                                 else
  222.                                     DoUpdate(&lMyEvent);
  223.                                 break;
  224.                             case activateEvt :
  225.                                 DoActivate(&lMyEvent);
  226.                                 break;
  227.                             case kHighLevelEvent:
  228.                                 DoHiLevEvent(&lMyEvent);
  229.                                 break;
  230.                             case osEvt :
  231.                                 DoOSEvent(&lMyEvent);
  232.                                 break;
  233.                             default:
  234.                                 if (DialogSelect(&lMyEvent, &dSelPtr, &theItemHit)) {
  235.                                     if (dSelPtr == dPtr && theItemHit) {
  236.                                         theFakeItem = theItemHit;
  237.                                         }
  238.                                     }
  239.                             }
  240.                         if (theFakeItem) {
  241.                             GetDialogItem(dPtr, theFakeItem, &type, &item, &box);
  242.                             switch (type) {
  243.                                 case ctrlItem+btnCtrl:
  244.                                     if ((theFakeItem >= ok) && (theFakeItem <= lastItemClosingDialog))
  245.                                         dialoging = false;
  246.                                     else if (userProc)
  247.                                         userProc(dPtr, item, theFakeItem);
  248.                                     break;
  249.                                 case ctrlItem+chkCtrl:
  250.                                     SetControlValue((ControlHandle)item, 1 - GetControlValue((ControlHandle)item));
  251.                                     if (userProc)
  252.                                         userProc(dPtr, item, theFakeItem);
  253.                                     break;
  254.                                 case ctrlItem+radCtrl:
  255.                                     if (GetControlValue((ControlHandle)item) == 0) {
  256.                                         SetControlValue((ControlHandle)item, 1);
  257.                                         for (spanPtr = things; (++spanPtr)->itemNumber != theFakeItem; )
  258.                                             ;
  259.                                         itemToBeActivated = spanPtr;
  260.                                         for (theGroup = spanPtr->group; (--spanPtr)->group == theGroup; )
  261.                                             ;
  262.                                         while ((++spanPtr)->refCon <= 0L)
  263.                                             ;
  264.                                         GetDialogItem(dPtr, spanPtr->itemNumber, &type, &item, &box);
  265.                                         SetControlValue((ControlHandle)item, 0);
  266.                                         spanPtr->refCon = 0L;
  267.                                         itemToBeActivated->refCon = 1L;
  268.                                         if (userProc)
  269.                                             userProc(dPtr, item, theFakeItem);
  270.                                         }
  271.                                     break;
  272.                                 case ctrlItem+resCtrl:
  273.                                 case editText:
  274.                                 case userItem:
  275.                                     if (userProc)
  276.                                         userProc(dPtr, item, theFakeItem);
  277.                                     break;
  278.                                 }
  279.                             }
  280.                         }
  281.                     else switch (lMyEvent.what) {
  282.                         case mouseDown :
  283.                             code = FindWindow(lMyEvent.where, &w);
  284.                             switch (code) {
  285.                                 case inMenuBar :
  286.                                     AdjustMenus();
  287.                                     menuSelected = MenuSelect(lMyEvent.where);
  288.                                     if ((wMenu = HiWord(menuSelected)) && wMenu == kRes_Menu_Edit) {
  289.                                         DoMovableModalMenuEdit(LoWord(menuSelected));
  290.                                         HiliteMenu(0);
  291.                                         }
  292.                                     else
  293.                                         Handle_My_Menu(menuSelected);
  294.                                     break;
  295.                                 case inSysWindow :
  296.                                     SystemClick(&lMyEvent, w);
  297.                                     AdjustMenus();
  298.                                     break;
  299.                                 case inContent :
  300.                                     SysBeep(30);
  301.                                     break;
  302.                                 case inDrag :
  303.                                     DoMovableModalDrag(w, lMyEvent.where);
  304.                                     break;
  305.                                 case inGoAway :
  306.                                     if (TrackGoAway(w, lMyEvent.where)) {
  307.             
  308.                                         }
  309.                                     break;
  310.         /*                        case inZoomIn :
  311.                                 case inZoomOut :
  312.                                     break;
  313.         */                        }
  314.                             break;
  315.                         case keyDown:
  316.                         case autoKey:
  317.                             DomyKeyEvent(&lMyEvent);
  318.                             break;
  319.                         case updateEvt :
  320.                             DoUpdate(&lMyEvent);
  321.                             break;
  322.                         case activateEvt :
  323.                             DoActivate(&lMyEvent);
  324.                             break;
  325.                         case kHighLevelEvent:
  326.                             DoHiLevEvent(&lMyEvent);
  327.                             break;
  328.                         case osEvt :
  329.                             DoOSEvent(&lMyEvent);
  330.                             break;
  331.                         }
  332.                     }
  333.                 else {
  334.                     if (IsDialogEvent(&lMyEvent))
  335.                         (void) DialogSelect(&lMyEvent, &dSelPtr, &theItemHit);
  336.                     DoIdle();
  337.                     }
  338.                 }
  339.             while (dialoging);
  340.         
  341.             if (theFakeItem == ok) {
  342.                 spanPtr = things;
  343.                 while (iNum = spanPtr->itemNumber) {
  344.                     GetDialogItem(dPtr, iNum, &type, &item, &box);
  345.                     theType = type & itemDisable ? type - itemDisable : type;
  346.                     switch(theType) {
  347.                         case ctrlItem+chkCtrl:
  348.                         case ctrlItem+resCtrl:
  349.                             spanPtr->refCon = GetControlValue((ControlHandle)item);
  350.                             break;
  351.                         case editText:
  352.                             GetDialogItemText(item, (StringPtr)spanPtr->refCon);
  353.                             break;
  354.                 //        case iconItem:
  355.                 //            break;
  356.                 //        case picItem:
  357.                 //            break;
  358.                 //        case userItem:
  359.                 //            break;
  360.                         }
  361.                     spanPtr++;
  362.                     }
  363.                 }
  364.             DisposeHandle(sControlItemList);
  365.             sControlItemList = nil;
  366.             if (cleanupProc)
  367.                 cleanupProc(dPtr);
  368.             }
  369.         if (dialogTopLeft) {
  370.             *dialogTopLeft = topLeft(dPtr->portRect);
  371.             LocalToGlobal(dialogTopLeft);
  372.             }
  373.         DisposFabWindow((FabWindowPtr)dPtr);
  374.         CloseDialog(dPtr);
  375.         SetPort(port);
  376.         AdjustMenus();
  377.         DrawMenuBar();
  378.         }
  379.     else
  380.         SysBeep(30);
  381.     DisposePtr(myStorage);
  382.     }
  383. else
  384.     SysBeep(30);
  385. InitCursor();
  386. return theFakeItem;
  387. }
  388.  
  389. void RecalcTextItems(FabWindowPtr w, RgnBalloonCursPtr theObj)
  390. {
  391. Rect    tempRect;
  392. Handle    item;
  393. short    type;
  394.  
  395. GetDialogItem((DialogPtr)w, theObj->itemID, &type, &item, &tempRect);
  396. RectRgn(theObj->zoneLocal, &tempRect);
  397. }
  398.  
  399. void DoMovableModalUpdate(DialogPtr dPtr)
  400. {
  401. UpdateDialog(dPtr, dPtr->visRgn);
  402. if (sDefaultItem)
  403.     OutlineButton(dPtr, sDefaultItem);
  404. }
  405.  
  406. void DimOrBlackenItems(EventRecord *passEvt, WindowPtr w, Boolean active)
  407. {
  408. ControlHandle    itemHandle;
  409. ControlHandle    *scanPtr;
  410. DialogPtr    theDialog;
  411. short    theItemHit;
  412. unsigned char    hiliting;
  413.  
  414. if (sControlItemList) {
  415.     HLockHi(sControlItemList);
  416.     scanPtr = (ControlHandle *)*sControlItemList;
  417.     while (itemHandle = *scanPtr++) {
  418.         if (active)
  419.             hiliting = GetControlReference(itemHandle);
  420.         else {
  421.             SetControlReference(itemHandle, (*itemHandle)->contrlHilite);
  422.             hiliting = 255;
  423.             }
  424.         if (hiliting != (*itemHandle)->contrlHilite) {
  425.             HiliteControl(itemHandle, hiliting);
  426.             ValidRect(&(*itemHandle)->contrlRect);
  427.             }
  428.         }
  429.     HUnlock(sControlItemList);
  430.     }
  431. if (sDefaultItem)
  432.     OutlineButton(w, sDefaultItem);
  433. (void) DialogSelect(passEvt, &theDialog, &theItemHit);
  434. }
  435.  
  436. void DoMovableModalMenuEdit(short theItem)
  437. {
  438. DialogPtr    dd;
  439.  
  440. if (SystemEdit(theItem - 1) == false) {
  441.     dd = FrontWindow();
  442.     if (dd && isMovableModal(dd))
  443.         switch (theItem) {
  444. //        case kMItem_Undo:
  445. //            break;
  446.             case kMItem_Cut:
  447. //                DialogCut(dd);
  448. //                (void) TEToScrap();
  449.                 PostEvent(keyDown, kCutKey);
  450.                 break;
  451.             case kMItem_Copy:
  452. //                DialogCopy(dd);
  453. //                (void) TEToScrap();
  454.                 PostEvent(keyDown, kCopyKey);
  455.                 break;
  456.             case kMItem_Paste:
  457. //                (void) TEFromScrap();
  458. //                DialogPaste(dd);
  459.                 PostEvent(keyDown, kPasteKey);
  460.                 break;
  461.             case kMItem_Clear:
  462.                 DialogDelete(dd);
  463.                 break;
  464.             }
  465.     }
  466. }
  467.  
  468. void DoMovableModalDrag(WindowPtr w, Point p)
  469. {
  470. EventRecord    tempEvt;
  471. GrafPtr        savePort;
  472. WindowPtr    f;
  473. register void (*theProc)(WindowPtr);
  474. //register RectPtr    wStateP;
  475.  
  476. f = FrontWindow();
  477. if (w != f && isMovableModal(f))
  478.     SysBeep(30);
  479. else {
  480.     DragWindow(w, p, &qd.screenBits.bounds);
  481.     GetPort(&savePort);
  482.     SetPort(w);
  483.     if (IsFabWindow(w)) {
  484.         theProc = ((FabWindowPtr)w)->dragProc;
  485.         if (theProc)
  486.             theProc(w);
  487.         RecalcGlobalCoords((FabWindowPtr)w);
  488.         }
  489.     (void) EventAvail(0, &tempEvt);
  490.     RecalcMouseRegion(w, tempEvt.where);
  491.     SetPort(savePort);
  492.     }
  493. }
  494.  
  495. void getDragRectMovMod(WindowPtr w, RectPtr r)
  496. {
  497. *r = w->portRect;
  498. }
  499.  
  500. void FabHiliteControl(ControlRef theControl, short hiliteState)
  501. {
  502. HiliteControl(theControl, hiliteState);
  503. SetControlReference(theControl, (*theControl)->contrlHilite);
  504. }
  505.  
  506.